package tss.common;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import admin.system.user.User;

import com.ffpc.sql.ConnectionFactory;
import com.ffpc.sql.DataException;
import com.ffpc.struts.StrutsMessage;

public abstract class DBServlet2 extends HttpServlet
{

    private static Logger logger = Logger.getLogger(DBServlet2.class);
	private ThreadLocal connectionFactory = new ThreadLocal();
	private ThreadLocal session = new ThreadLocal();

  /**
   * Initialize global variables
   */

  @Override
public void init(ServletConfig config) throws ServletException
  {
    super.init(config);
  }


  /**
   * Process the HTTP Get request
   */
  @Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
  {
      doAction(request,response);
  }

  /**
   * Process the HTTP Post request
   */
  @Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
  {
      doAction(request,response);
  }

  private final void doAction (HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
  {
      String forward = new String("forward");
      boolean exception = false;
      try
        {
            connectionFactory.set(new ConnectionFactory("fasp_tss"));
            session.set(request.getSession());
            StrutsMessage message = new StrutsMessage();
            request.setAttribute("message",message);
            if (isLogin())
            {
                forward = perform(request, response, message);
                logger.info("forward : " + forward ) ;
            }
            else
            {
                message.setMessage("You may haven't login or your session is timeout.");
                forward = "Login.jsp";
            }
        }
        catch (DataException de)
        {
        	 logger.error("", de);
            try
            {
            	if (getConnectionFactory() != null)
            		getConnectionFactory().rollback();
                printErr(request,response,de);
            }
            catch (Exception e)
            {
                logger.error("", e);
            }
            finally{
                exception = true;
            }
        }
        catch (Exception ex)
        {
        	logger.error("", ex);
            try
            {
            	if (getConnectionFactory() != null)
            		getConnectionFactory().rollback();
                printErr(request,response,ex);
                
            }
            catch (Exception e)
            {
                logger.error("", e);
            }
            finally{
                exception = true;
            }
        }
        finally
        {
            try
            {
            	if (getConnectionFactory() != null)
            		getConnectionFactory().finalize();
                if (!exception && forward != null)
                    this.forward(forward,request,response);
            }
            catch (Exception e)
            {
                logger.error("", e);
            }
            
        	connectionFactory.set(null);
        	session.set(null);
        }
  }
  
  private final ConnectionFactory getConnectionFactory() {
	  return (ConnectionFactory) connectionFactory.get();
  }
  
  protected final String getSID()
  {
    return getConnectionFactory().getSID();
  }
  protected final Connection getConnection()
  {
    return getConnectionFactory().getConnection();
  }
  protected final String getconnUsername()
  {
    return getConnectionFactory().getUsername();
  }

  protected final String getconnUserpass()
  {
    return getConnectionFactory().getPassword();
  }
  protected final Map getParameterMap(HttpServletRequest request)
  {
    HashMap map = new HashMap();
    for (Enumeration e=request.getParameterNames(); e.hasMoreElements();)
    {
      String key=(String)e.nextElement();
      if (!map.containsKey(key))
        map.put(key,request.getParameter(key));
    }
    return map;
  }

  protected final Map getParameterValuesMap(HttpServletRequest request)
  {
    HashMap map = new HashMap();
    for (Enumeration e=request.getParameterNames(); e.hasMoreElements();)
    {
      String key=(String)e.nextElement();
      if (!map.containsKey(key))
        map.put(key,request.getParameterValues(key));
    }
    return map;
  }

  protected void forward(String path, HttpServletRequest request, HttpServletResponse response) {
    try
    {

      String forwardStr = "/" + path;
      logger.info(forwardStr);

      this.getServletContext().getRequestDispatcher(forwardStr).forward(request, response);
    }
    catch (Exception ex)
    {
      logger.error("", ex);
    }
  }

  private void printErr(HttpServletRequest request,HttpServletResponse response,DataException e)
  {
    printErr(request,response,"Data error, request failed!",e);
  }

  private void printErr(HttpServletRequest request,HttpServletResponse response,SQLException e)
  {
    printErr(request,response,"Database error, request failed!",e);
  }

  private void printErr(HttpServletRequest request,HttpServletResponse response,ParseException e)
  {
    printErr(request,response,"Invalid date or numeric format, request failed!",e);
  }

  private void printErr(HttpServletRequest request,HttpServletResponse response,Exception e)
  {
    printErr(request,response,"Servlet Exception throw, request failed!",e);
  }

  private void printErr(HttpServletRequest request,HttpServletResponse response,String errorMessage,Exception e)
  {
    try
    {
        logger.error("", e);
        response.setContentType("text/html;");
        PrintWriter pwriter = new PrintWriter(response.getOutputStream());
        StringBuffer outputMessage =
          new StringBuffer("<html><head></head><body><SCRIPT FOR=window EVENT=onload>alert(\" ")
              .append(errorMessage)
              .append(" ")
              .append(replace(replace((e.getMessage()==null?new String(""):e.getMessage()),13,""),10,"").replace('"',' '))
              .append("\");history.back();</SCRIPT></body></html>");
        pwriter.print(outputMessage.toString());
        pwriter.flush();
        pwriter.close();
    }
    catch (Exception ex)
    {
      logger.error("", ex);
    }
  }

  /*protected void redirect(String path)
    throws IOException, DataException
  {
    this.connectionFactory.finalize();
    response.sendRedirect(new StringBuffer(request.getContextPath()).append("/").append(path).toString());
  }*/

  protected String replace(String str, int ch, String replaceStr)
  {
    if (str.indexOf(ch)==-1)
      return str;
    StringBuffer newStr  = new StringBuffer(str.substring(0,str.indexOf(ch)));
           newStr = newStr.append(replaceStr).append(str.substring(str.indexOf(ch) + 1,str.length()));
    return newStr.toString();
  }

  protected final User getUser()
  {
      return (User) getSession().getAttribute("user");
  }

  protected boolean isLogin()
  {
      return getUser() != null;
  }

  protected final HttpSession getSession()
  {
      return (HttpSession) session.get();
  }

  protected Timestamp getDate()
  {
    return new Timestamp(System.currentTimeMillis());
  }

  protected abstract String perform(HttpServletRequest request, HttpServletResponse response, StrutsMessage message)
    throws ServletException, IOException, SQLException, DataException,Exception;

}

